#include "DataFormatter.h"
#include <QRegExp>

/**
 * @brief 解析用户输入为二进制数据
 * @param input 原始输入字符串
 * @param hexMode 是否为十六进制输入模式
 * @param ok 输出解析是否成功
 * @param error 输出错误信息（当解析失败时）
 * @return 解析得到的二进制数据
 */
QByteArray DataFormatter::parseInput(const QString &input, bool hexMode, bool *ok, QString *error) {
    if (ok) *ok = true;
    if (error) error->clear();

    if (!hexMode) {
        return input.toUtf8();
    }

    QString dataStr = input.simplified();
    dataStr.replace(" ", "");

    QRegExp hexMatcher("^[0-9A-Fa-f]+$");
    if (!hexMatcher.exactMatch(dataStr)) {
        if (ok) *ok = false;
        if (error) *error = QString::fromLatin1("Invalid hexadecimal input");
        return QByteArray();
    }

    if (dataStr.length() % 2 != 0) {
        // 补齐奇数字节的情况：前置一个0
        dataStr = "0" + dataStr;
    }

    QByteArray data;
    bool byteOk = true;
    for (int i = 0; i < dataStr.length(); i += 2) {
        QString byteStr = dataStr.mid(i, 2);
        uint8_t byte = byteStr.toUInt(&byteOk, 16);
        if (!byteOk) {
            if (ok) *ok = false;
            if (error) *error = QString::fromLatin1("Failed to parse hex at position %1").arg(i);
            return QByteArray();
        }
        data.append(static_cast<char>(byte));
    }
    return data;
}

/**
 * @brief 将二进制数据转换为显示字符串
 * @param data 二进制数据
 * @param hexMode 是否以十六进制显示
 * @return 显示用字符串（十六进制或文本，文本模式替换不可打印字符为'.'）
 */
QString DataFormatter::toDisplayString(const QByteArray &data, bool hexMode) {
    if (hexMode) {
        QString hexStr;
        hexStr.reserve(data.size() * 3);
        for (unsigned char c : data) {
            hexStr.append(QString("%1 ").arg(c, 2, 16, QLatin1Char('0')).toUpper());
        }
        return hexStr.trimmed();
    }

    QString textStr;
    textStr.reserve(data.size());
    for (unsigned char c : data) {
        if (c >= 32 && c <= 126) {
            textStr.append(QChar(c));
        } else {
            textStr.append("⊗");
        }
    }
    return textStr;
}
